Merge pull request #284 from rloomba/add_stubhub_agent

Add Stubhub Agent

Andrew Cantino 11 years ago
parent
commit
269ed20194

+ 100 - 0
app/models/agents/stubhub_agent.rb

@@ -0,0 +1,100 @@
1
+module Agents
2
+  class StubhubAgent < Agent
3
+    cannot_receive_events!
4
+
5
+    description <<-MD
6
+      This StubHubAgent creates an event for a given StubHub Event. It can be used to track how many tickets are available for the event and the minimum and maximum price. All that is required is that you paste in the url from the actual event, e.g. http://www.stubhub.com/outside-lands-music-festival-tickets/outside-lands-music-festival-3-day-pass-san-francisco-golden-gate-park-polo-fields-8-8-2014-9020701/
7
+    MD
8
+
9
+    event_description <<-MD
10
+      Events looks like this:
11
+        {
12
+          "url": "http://stubhub.com/valid-event-url"
13
+          "name": "Event Name"
14
+          "date": "2014-08-01"
15
+          "max_price": "999.99"
16
+          "min_price": "100.99"
17
+          "total_postings": "50"
18
+          "total_tickets": "150"
19
+          "venue_name": "Venue Name"
20
+        }
21
+    MD
22
+
23
+    default_schedule "every_1d"
24
+
25
+    def working?
26
+      event_created_within?(1) && !recent_error_logs?
27
+    end
28
+
29
+    def default_options
30
+      { 'url' =>  'http://stubhub.com/enter-your-event-here' }
31
+    end
32
+
33
+    def validate_options
34
+      errors.add(:base, 'url is required') unless options['url'].present?
35
+    end
36
+
37
+    def url
38
+      options['url']
39
+    end
40
+
41
+    def check
42
+      create_event :payload => fetch_stubhub_data(url)
43
+    end
44
+
45
+    def fetch_stubhub_data(url)
46
+      StubhubFetcher.call(url)
47
+    end
48
+
49
+    class StubhubFetcher
50
+
51
+      def self.call(url)
52
+        new(url).fields
53
+      end
54
+
55
+      def initialize(url)
56
+        @url = url
57
+      end
58
+
59
+      def event_id
60
+        /(\d*)\/{0,1}\z/.match(url)[1]
61
+      end
62
+
63
+      def base_url
64
+       'http://www.stubhub.com/listingCatalog/select/?q='
65
+      end
66
+
67
+      def build_url
68
+        base_url + "%2B+stubhubDocumentType%3Aevent%0D%0A%2B+event_id%3A#{event_id}%0D%0A&start=0&rows=10&wt=json"
69
+      end
70
+
71
+      def response
72
+        uri = URI(build_url)
73
+        Net::HTTP.get(uri)
74
+      end
75
+
76
+      def parse_response
77
+        JSON.parse(response)
78
+      end
79
+
80
+      def fields
81
+        stubhub_fields = parse_response['response']['docs'][0]
82
+        {
83
+          'url' => url,
84
+          'name' => stubhub_fields['seo_description_en_US'],
85
+          'date' => stubhub_fields['event_date_local'],
86
+          'max_price' => stubhub_fields['maxPrice'].to_s,
87
+          'min_price' => stubhub_fields['minPrice'].to_s,
88
+          'total_postings' => stubhub_fields['totalPostings'].to_s,
89
+          'total_tickets' => stubhub_fields['totalTickets'].to_i.to_s,
90
+          'venue_name' => stubhub_fields['venue_name']
91
+        }
92
+      end
93
+
94
+      private
95
+
96
+      attr_reader :url
97
+
98
+    end
99
+  end
100
+end

+ 17 - 0
spec/data_fixtures/stubhub_data.json

@@ -0,0 +1,17 @@
1
+{
2
+  "response":{
3
+    "docs":[
4
+      {
5
+      "url": "http://www.stubhub.com/event/name-1-1-2014-12345",
6
+      "seo_description_en_US": "name",
7
+      "event_date_local": "2014-01-01",
8
+      "maxPrice": "100",
9
+      "minPrice": "50",
10
+      "totalPostings": "100",
11
+      "totalTickets": "200",
12
+      "venue_name": "Venue Name"
13
+    }
14
+    ]
15
+  }
16
+}
17
+

+ 67 - 0
spec/models/agents/stubhub_agent_spec.rb

@@ -0,0 +1,67 @@
1
+require 'spec_helper'
2
+
3
+describe Agents::StubhubAgent do
4
+
5
+  let(:name) { 'Agent Name' }
6
+  let(:url) { 'http://www.stubhub.com/event/name-1-1-2014-12345' }
7
+  let(:parsed_body) { JSON.parse(body)['response']['docs'][0] }
8
+  let(:valid_params) { { 'url' => parsed_body['url'] } }
9
+  let(:body) { File.read(Rails.root.join('spec/data_fixtures/stubhub_data.json')) }
10
+  let(:stubhub_event_id) { 12345 }
11
+  let(:response_payload) { {
12
+                            'url' => url,
13
+                            'name' => parsed_body['seo_description_en_US'],
14
+                            'date' => parsed_body['event_date_local'],
15
+                            'max_price' => parsed_body['maxPrice'],
16
+                            'min_price' => parsed_body['minPrice'],
17
+                            'total_postings' => parsed_body['totalPostings'],
18
+                            'total_tickets' => parsed_body['totalTickets'],
19
+                            'venue_name' => parsed_body['venue_name']
20
+                            } }
21
+
22
+  before do
23
+      stub_request(:get, "http://www.stubhub.com/listingCatalog/select/?q=%2B%20stubhubDocumentType:event%0D%0A%2B%20event_id:#{stubhub_event_id}%0D%0A&rows=10&start=0&wt=json").
24
+         to_return(:status => 200, :body => body, :headers => {})
25
+
26
+    @stubhub_agent = described_class.new(name: name, options: valid_params)
27
+    @stubhub_agent.user = users(:jane)
28
+    @stubhub_agent.save!
29
+  end
30
+
31
+
32
+  describe "#check" do
33
+
34
+    it 'should create an event' do
35
+      expect { @stubhub_agent.check }.to change { Event.count }.by(1)
36
+    end
37
+
38
+    it 'should properly parse the response' do
39
+      event = @stubhub_agent.check
40
+      event.payload.should == response_payload
41
+    end
42
+  end
43
+
44
+  describe "validations" do
45
+    before do
46
+      @stubhub_agent.should be_valid
47
+    end
48
+
49
+    it "should require a url" do
50
+      @stubhub_agent.options['url'] = nil
51
+      @stubhub_agent.should_not be_valid
52
+    end
53
+
54
+  end
55
+
56
+  describe "#working?" do
57
+    it "checks if events have been received within the expected receive period" do
58
+      @stubhub_agent.should_not be_working
59
+
60
+      Agents::StubhubAgent.async_check @stubhub_agent.id
61
+      @stubhub_agent.reload.should be_working
62
+      two_days_from_now = 2.days.from_now
63
+      stub(Time).now { two_days_from_now }
64
+      @stubhub_agent.reload.should_not be_working
65
+    end
66
+  end
67
+end